﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Solidi
{
	public static class DependencyContainerExtensions
	{
		public static void RegisterFromBuilder(this IDependencyContainer source, IDependencyBuilder builder)
		{
            if (builder == null)
            {
                throw new ArgumentNullException("builder");
            }

			Register(source, builder.Dependencies);
		}

		public static void Register(this IDependencyContainer source, IEnumerable<IDependency> dependencies)
		{
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

			source.Registry.Add(dependencies);
		}

		public static bool TryResolve<T>(this IDependencyContainer source, out T instance)
		{
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

			object o;

			bool success = source.Resolver.TryResolve(source, new DependencyKey(typeof(T)), out o);

			if (success)
			{
				instance = (T)o;
			}
			else
			{
				instance = default(T);
			}

			return success;
		}

		public static object Resolve(this IDependencyContainer source, Type type)
		{
			return Resolve(source, new DependencyKey(type));
		}

		public static object Resolve(this IDependencyContainer source, Type type, string name)
		{
			return Resolve(source, new DependencyKey(type, name));
		}

		public static T Resolve<T>(this IDependencyContainer source, string name)
		{
			return (T)Resolve(source, new DependencyKey(typeof(T), name));
		}

		public static object Resolve(this IDependencyContainer source, IDependencyKey key)
		{
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

			return source.Resolver.Resolve(source, key);
		}

		public static T Resolve<T>(this IDependencyContainer source)
		{
			return (T)Resolve(source, new DependencyKey(typeof(T)));
		}

		public static bool TryRelease(this IDependencyContainer source, object instance)
		{
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

			return source.Resolver.TryRelease(source, instance);
		}

		public static void Release(this IDependencyContainer source, object instance)
		{
			source.TryRelease(instance);
		}

		public static void ReleaseAll(this IDependencyContainer source)
		{
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }

			source.Lifetime.DiscardAll(source, false);
		}
	}
}
